package oen.game.gateway.network;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.net.InetSocketAddress;

/**
 * <p>描述：Netty服务器端</p>
 *
 * <p>创建时间：2021-11-10 09:35</p>
 * <p>更新时间：暂无</p>
 *
 * @author Kevin.Xu
 * @version 1.0
 */
public class NettyServer {

    private int port;
    private LogLevel level;
    private ChannelInitializer<SocketChannel> channelChannelInitializer;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private ServerBootstrap serverBootstrap;

    public NettyServer(int port, LogLevel level, ChannelInitializer<SocketChannel> channelChannelInitializer) {
        this.port = port;
        this.level = level;
        this.channelChannelInitializer = channelChannelInitializer;

        this.init();
    }

    private void init() {
        bossGroup = new NioEventLoopGroup(1);
        workerGroup = new NioEventLoopGroup();

        serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workerGroup);

        serverBootstrap.option(ChannelOption.SO_BACKLOG, 256);
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
        serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);

        serverBootstrap.channel(NioServerSocketChannel.class);
        serverBootstrap.handler(new LoggingHandler(level));
        serverBootstrap.childHandler(channelChannelInitializer);
    }

    public void start() throws InterruptedException {
        ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(port)).sync();
        channelFuture.channel().closeFuture().sync();
    }

    public void stop() {
        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
    }
}
